Teil V Dateiformate An sich sollte es selbstverst„ndlich sein, dass eine Programmdokumentation auch eine Be- schreibung der verwendeten Dateiformate enth„lt. Wie so vieles ist es das nicht, was mich aber nicht hindern soll, hier mit gutem Beispiel voranzugehen. 1 CHAOSultd-Bilder CHAOSultd verwendet fr Bilder ein eigenes Format34 Eine Bilddatei besteht aus einem Header, der Farbtabelle, den Parametern, zus„tzlichen Parametern und den Bilddaten, wobei letztere immer gepackt werden, auch dann, wenn sie dadurch l„nger werden35. Der Header sieht (als C-Struktur) folgendermassen aus: typedef struct - /* id's */ char chaos_id[8]; /* CHSultd5 */ char frac_id[8]; /* gr”sse, planes und colors */ unsigned int size_x; unsigned int size_y; unsigned int planes; unsigned int colors; /* zus. parameter */ int lastline; int last_flag; int xor_offset; /* l„nge der folgenden daten */ long par_len; long xpar_len; long pic_len; /* coltab in long */ /* parameter */ /* zus. parameter */ /* bilddaten */ " FRAC_HEAD; chaos_id ist eine Kennung, die die Zeichen CHSultd5 beinhalten muss. frac_id ist eine wei- tere Kennung, die die Berechnungsroutine, die fr das Bild verantwortlich ist, kennzeichnet. ____________________________________34 Wozu Standartformate verwenden, wenn man auch eigene definieren kann? Aber im Ernst: die verschiedenen Bildgr”ssen und die Verwaltung der Parameter liessen mir ei* *n spezielles Format sinnvoll erscheinen und wenn man sowieso ein eigenes Format verwendet, ist es auch schon* * egal, wie speziell dieses Format dann ist (denkbar w„re h”chstens noch ein GEM-Image-Format gewesen, mi* *t einem erweiterten Header; vielleicht fhre ich das mal als alternatives Format ein). 35das ist kein Scherz, das kann wirklich passieren, die Daten werden aber nicht nennenswert l* *„nger 45 size_x, size_y, planes und colors legen die Bildgr”sse, die Anzahl der Bitebenen und die Zahl der Farben fest. Die Bildgr”sse ist - unabh„ngig davon, ob und wieweit das Bild schon berechnet wurde - die Gr”sse des fertig berechneten Bildes. lastline gibt an, ob das Bild fertig ist oder nicht. Ist lastline 0, so gibt es gar keine Bilddaten, -1 bedeutet, dass das Bild fertig berechnet ist. Andernfalls gibt lastline die Anzahl der berechneten und gespeicherten Zeilen an, aber nur falls das unterste Bit in last_flag gesetzt ist36. Ist dieses Bit gel”scht, so ist fr lastline6= 0 stets das gesammte Bild gespeichert. xor_offset ist fr das Packen der Daten von Bedeutung und wird gleich erkl„rt; par_len, xpar_len und pic_len gibt die L„nge der drei Datenbl”cke an. Die Parameter und zus. Parameter sind natrlich Bildtypabh„ngig, bleiben also die Bilddaten. Im Farbmodus werden zun„chst die Bitplanes, die im Screen-Format ja wortweise hinter- einanderstehen getrennt, d.h. es kommt erst die ganze Bitplane 0, dann 1 usw. (man hat also gewissermassen ein GEM-Standartformat, wobei die Gr”sse des Blockes durch size_x und size_y festgelegt ist). Dann werden die Bilddaten von hinten mit dem xor_offset mit sich selbst via xor ver- knpft. Der Offset entspricht im Allgemeinen einer oder mehreren Bildschirmzeilen. Da- durch entsteht ein Bild, dessen Zeilen (ausser der ersten) immer nur die Differenz zur darberliegenden Zeile beinhalten und das deshalb i.a. besser zu packen ist. Ist xor_offset 0 so entf„llt die Xor-Verknpfung. Um die Xor-Verknpfung beim Laden rckg„ngig zu machen muss man die Daten erneut via xor miteinander verknpfen, diesmal allerdings von vorne. Anschliessend werden die Bilddaten im Stad-Format gepackt und gespeichert. Das heisst die gepackten Daten beginnen mit den drei Bytes Kennbyte, Packbyte und Spe- zialbyte, anschliessend folgen die gepackten Graphikdaten, wobei folgende Kodierungen An- wendung finden: Das Kennbyte und das nachfolgende Byte n bedeuten, dass das Packbyte n+1 mal zusam- mengefasst wurde. Das Spezialbyte und die beiden nachfolgenden Bytes a und n bedeuten, dass das Byte a n+1 mal zusammengefasst wurde. Alle anderen Bytes mssen so wie sie in der Datei stehen in das Bild bernommen werden. 2 Filme Film-Dateien haben sich gegenber FRACTAL Version 4.1 (und 4.3) nicht ge„ndert. Sie bestehen aus dem Header 'film', der (als 2 Byte Integer abgelegten) Anzahl verschie- dener Bilder sowie der Anzahl der Bilder im Film. Es folgen die Anzeigeoptionen (eine SHOW_OPTS-Struktur), daran schliessen sich die Informationen ber die im Film enthal- tenen Bilder an. Und zwar fr jedes Bild Dateipfad, Name und Dateiextension, jeweils als nullterminierter String (unter diesen Dateinamen werden die Bilder beim Einladen eines Filmes gesucht). Deshalb ist es auch n”tig, dass die Bilder beim Speichern des Filmes ge- speichert sind, FRACTAL k”nnte sonst h”chstens raten, wohin man die Bilder abspeichern wird. Dateipfade k”nnen (seit FRACTAL V4.3) relativ sein, sie beginnen dann nicht mit einem Laufwerk. In diesem Fall ist der Pfad relativ zum Verzeichnis der Filmdatei zu ver- stehen. ____________________________________36 die anderen Bits sind reserviert 46 Zuletzt folgt eine Liste mit der Reihenfolge der Bilder im Film, wobei sich die Nummern (1 Byte Integer) auf die Reihenfolge der Dateinamen beziehen. Filmdateien drfen nicht l„nger als 32000 Bytes sein. 3 Einstellungen Die Einstellungsdateien will ich hier nicht im Detail erl„utern, da sie sicher nicht sonderlich interessant sind. Eventuell doch von Interesse ist allerdings der prinzipielle Aufbau dieser Dateien, die ja nicht nur die Voreinstellungen von CHAOSultd selbst, sondern auch die der diversen Be- rechungsroutinen - letztere in nicht festgelegter Reihenfolge und wom”glich wechselnder Anzahl. Realisiert wird dies durch eine Block-Struktur. Jeder Block beginnt mit einem 12 Byte langen Header: die ersten 8 Byte erhalten eine Kennung (CHAOSultd verwendet fr seine Einstellungen CHSultd5, fr die Berechnungsroutinen wird die gleiche Kennung verwendet wie in Bilddateien. Es folgt als Langwort (4 Byte) die L„nge der folgenden Daten. Ansch- liessend kommen die Einstellungsdaten sebler, deren Inhalt von den Berechnungsroutinen abh„ngt; die CHAOSultd-Einstellungen bestehen aus einer CHS_SET-Struktur, die in der Headerdatei XCOMMON.H definiert ist. 47 Teil VI die Schnittstelle fr externe Routinen Die folgenden Erl„uterungen sind nur fr Programmierer bestimmt, die eigene Berechnungs- routinen fr Bilder irgendeiner Art schreiben wollen. Aus technischen Grnden ist es nicht ratsam dies in einer anderen Sprache als C37 und vermutlich auch da wiederum nur in Pure C (bzw. Turbo C) zu versuchen. Wie weit andere C-Compiler mit den Parameterbergabe-Konventionen von Turbo/Pure C zurecht kommen weiss ich nicht (vermutlich eher nicht, Turbo/Pure C bergibt Parameter auch in Registern). Man sei sich auch darber im Klaren, dass die eigentliche Berechnungsroutine (jedenfalls solange man sie nicht sehr aufwendig optimiert) meist nur einen kleinen Teil der n”tigen Routinen darstellt, insbesondere sollte man in der Lage sein, mit GEM-Dialogboxen umzu- gehen. Ich setze im folgenden stets vorraus, dass Interessenten in C programmieren k”nnen, insbesondere den Umgang mit Strukturen beherrschen, ebenso die Programmierung von GEM-Programmen. Wie aber werden externe Routinen berhaupt eingebunden? Und welches Format muss die erzeugte XCH-Datei haben? Um die zweite Frage zuerst zu beantworten: bei der XCH-Datei handelt es sich um eine normale Programm-Datei, die aber keinen Startup-Code besitzt. Erzeugen kann man eine solche Datei mit Pure C, indem man in der Projektdatei einfach den Startup-Code wegl„sst (man kann das so erzeugte Programm natrlich nicht vom Desktop aus ausfhren). Das Programm enth„lt auch keine Funktion main, eingebunden wird es vielmehr so, dass die erste Funktion der Source-Datei nach dem Laden und Relozieren aufgerufen wird (bei mehreren Sourcedateien ist es die erste Funktion der ersten Sourcedatei, es kommt nur dar- auf an, dass diese Funktion am Anfang des TEXT-Segmentes steht, was man gegebenenfalls mit einem Debugger berprfen sollte). Diese Funktion hat nur zwei Aufgaben: erstens wird ihr von CHAOSultd ein Zeiger auf eine Struktur mit Routinen und globalen Variablen bergeben, die CHAOSultd den externen Routinen zur Verfgung stellt, und zweitens gibt die Routine an CHAOSultd einen Zeiger auf eine Struktur zurck, in der die Adressen der externen Routinen stehen. Das war's dann gewissermassen schon, zum Initialisieren der externen Routinen wird speziell eine der Routinen aufgerufen. 1 Beschreibung der ben”tigten Routinen Zun„chst eine Vorbemerkung: ich bin kein sonderlich guter Programmierer und insbesondere programmiere ich zwar nicht konzeplos aber doch mit viel zu oft wechselnden Konzepton. Dies macht sich auch bei den bereitzustellenden Routinen bemerkbar, etwa dadurch, dass mal der Bildschirm vor Ausgabe einer Dialogbox schon gesichert ist, mal noch zu sichern ist. Auch Rckgabecodes sind nicht unbedingt einheitlich. Sorry, das ist sicher nicht sehr gelungen, aber die Schnittstelle ist halt nach und nach entstanden. Was bei den Routinen jeweils zu beachten ist wird aber im Folgenden ausfhrlich erl„utert. ____________________________________37 in Frage k„me h”chstens noch Assembler, aber es erscheint mir bertrieben, die ganzen Ro* *utinen zur Parameter-Ein- und Ausgabe in Assembler zu schreiben 48 Alle Angaben und Routinen mssen in eine CHAOS-Struktur eingetragen werden, die dann bei der Initialisierung an CHAOSultd bergeben wird (genaueres siehe unten). Die n”tigen Struktur-Deklarationen finden sich alle in der Headerdatei XCOMMON.H. CHAOS- ultd gibt es bekanntlich in zwei Versionen, sw- und Farb-Version, diese haben einen ge- meinsamen Quelltext, in dem jedoch mittels bedingter Compilierung zwischen den Ver- sionen unterschieden wird. Fr die Farb-Version ist das Makro COLOR definiert (mittels #define COLOR, oder einer Compileroption -dCOLOR), fr die sw-Version nicht. Dies gilt auch fr die XCOMMON-Headerdatei. 1.1 allgemeine Angaben id char id[8]; Kennung der Routine, die auch in allen Bilddateien und fr den Parameter-Block in der Einstellungsdatei verwendet wird. Mein Vorschlag ist, die ersten vier Zeichen als Kennung fr den Autor, die anderen vier als Kennung fr die Routine zu verwenden (dementsprechend beginnen meine Kennungen auch alle mit TMMW). menue char *menue; Zeiger auf den Meneintrag des Programmes (ohne vorangestellte Leerzeichen und Tasta- turbefehl). Dieser darf maximal 16 Zeichen lang sein, er wird auch bei der Auflistung der Berechnungsroutinen im Programm-Info verwendet. name, version und text char *name; char *version; char *text; Diese drei Texte werden ausschliesslich fr das Programminfo verwendet. name sollte den Namen des Programmautors (max. 24 Zeichen), version eine Versionsnummer und ein Erstellungsdatum (max. 20 Zeichen) und text eine allgemeine Kurzbeschreibung (max. 64 Zeichen) enthalten (die Texte sind nicht optional, will man nichts angeben, so mssen die Zeiger mindestens auf einen Leerstring zeigen). icon und xicon ICONBLK *icon; ICONBLK *xicon; Zeiger auf Icon fr die Anzeige der Bilder auf dem Desktop. icon wird fr nicht gespeicherte Bilder, xicon fr gespeicherte verwendet; Konvention ist, gespeicherte Bilder mit einem Haken zu kennzeichnen. Die Icon mssen eine Gr”sse von 48x24 Punkten haben, der Buchstabe des Icons wird fr die Kennzeichnung der Bildgr”sse verwendet und sollte oben links liegen. 49 set_len und set long set_len; void *set; set_len bezeichnet die L„nge der Voreinstellungen, set zeigt auf diese (man muss also fr die Voreinstellungen eine Struktur anlegen sowie eine globale Variable, auf deren Adresse man dann in set eintr„gt). par_len long par_len; L„nge der Bildparameter make_len long make_len; L„nge der Eingabeparameter fr das Erzeugen neuer Bilder, im folgenden auch als Bild(er)parameter bezeichnet. neu_len long neu_len; L„nge der Parameter fr make_neu. neu_par und neu_flag void *neu_par; int neu_flag; Flags fr make_neu, siehe Beschreibung der make_neu-Routinen last_flag int last_flag; Flag: falls last_flag 1 ist, so entspricht ein lastline-Wert gr”sser Null in den Objekt- Parametern der letzten berechneten Bildschirmzeile. Ist last_flag 0, so wird immer der ganze Bildschirm abgelegt. 1.2 Routinen Mit Ausnahme der Routinen do_init, get_param, get_picpar und do_draw sind alle Rou- tinen optional, d.h. sie k”nnen fehlen, ohne dass dies zu Programm-Abstrzen fhrt. Diese drei Routinen stellen natrlich nur die Minimalanforderungen an die Berechnungsroutinen dar, mit ihnen kann man lediglich Bilder erzeugen. do_init int do_init(int nr); Die Routine wird beim Programmstart aufgerufen. Sie sollte alle globalen Initialisierungen vornehmen, also etwa Resourcen laden usw. Der Parameter nr ist die Typ-Nummer der Routine unter der diese intern verwaltet wird. 50 Zurckgeben muss die Routine 0, falls erfolgreich initialisiert wurde, konnte die Routine nicht initialisiert werden, so gibt man 1 zurck, die Berechnungsroutinen werden dann nicht aufgenommen. Anmerkung: nicht kmmern muss sich die Routine um das Laden der Voreinstellung. Sie werden von CHAOSultd selbst geladen. In der Initialisierungsroutine stehen sie allerdings noch nicht zur Verfgung. get_param int get_param(void *param, X_PARAM *x_param); Diese Routine dient der Eingabe der Bildparameter fr neu zu berechnende Bilder. param ist ein Zeiger auf die Parameter fr die Erzeugung neuer Bilder. Diese Parameter sind i.a. nicht direkt die Parameter eines Bildes, es soll ja auch die Erzeugung von Bildfolgen m”glich sein. x_param ist ein Zeiger auf eine Strukur mit zus„tzlichen, Bildtyp-unabh„ngigen Parametern, die die Routine get_param ausfllen muss. typedef struct - int anzahl; /* Anzahl der zu erzeugenden Bilder */ int size; /* Bildgr”sse (0 klein, 1 mittel, 2 gross) */ #ifndef COLOR int color; /* 0 normal, 1 invers */ #else int col_tab[16]; /* Farbtabelle */ #endif int xor_offset; char name[16]; char path[64]; " X_PARAM; Das drfte weitgehend klar sein. xor_offset ist der gleiche Wert wie auch in Bild-Dateien. Er wird in Byte angegeben. Wichtig ist, dass bei Berechnungsabbruch mindestens soviele Bilddaten vorliegen, wie xor_offset angibt, sonst kommt es zum Crash (das kann eigentlich nur vorkommen, wenn das Bild nur soweit berechnet gespeichert wird (also wenn last_flag 1 ist). xor_offset ist normalerweise ein Vielfaches der Zeilenl„nge oder 0 (kein Xor beim Packen). Die Routine braucht sich nicht um das Sichern und Restaurieren des Bildhintergrundes kmmern; Rckgabewerte sind 0 im Falle eines Abbruches und 1 fr Ok, also fr das Erzeugen der Bilder. get_picpar void *get_picpar(void *param_in, int nr,int anzahl); Diese Routine muss aus den von get_param eingelesenen Parametern (fr ein oder mehrere Bilder) die Parameter eines konkreten Bildes machen. šbergeben wird ein Zeiger auf die Bild(er)parameter (param_in), die Nummer des aktuell zu erzeugenden Bildes (nr, gez„hlt wird von 0 an) und die Gesamtzahl der zu erzeugenden Bilder. 51 Zurckliefern muss die Routine die Parameter des Bildes Nummer nr. Dabei handelt es sich jetzt wirklich um die Parameter eines Bildes, wie sie dann auch von CHAOSultd verwaltet werden sollen. Im einfachsten Fall, wenn die Berechnungsroutinen nur die Erzeugung einzelner Bilder zul„sst, k”nnen die Bild(er)parameter natrlich mit den Bildparametern bereinstimmen, und diese Routine hat nichts weiter zu tun, als den Zeiger param_in wieder zurckzugeben. L„sst man die Berechnung mehrerer Bilder zu, so mssen die Parameter fr das aktuelle Bild interpoliert werden. Fr die Bildparameter mit den interpolierten Werten sollte man dabei in den Bild(er)parametern Platz bereithalten, da man sie natrlich nicht auf dem Stack ablegen kann und globale Variablen unn”tig Speicherplatz brauchen. set_param void set_param(void); Diese Routine ist zur Eingabe der Voreinstellungen der Parameter gedacht. Der Bildschirm- hintergrund wird vor Aufruf gesichert und nachher restauriert. Die Parameter mssen natrlich in dem in set angegebenen Speicherbereich verwaltet wer- den, wenn sie korrekt gespeichert werden sollen. extended void extended(void); Diese Routine wird bei Anklicken des Menpunktes der Berechnungsroutinen mit CONTROL aufgerufen. Hierfr ist keine besondere Funktion vorgesehen, man kann mit der Routine machen was man will. Wie bei set_param wird der Bildschirm gerettet und restauriert. get_neu_param int get_neu_param(void *param); Mit dieser Routine werden die Parameter fr neu berechnen eingegeben. param ist ein Zeiger auf die zugeh”rigen Parameter, in den die Routine die eingelesenen Werte eintragen muss. Die Routine muss darberhinaus die Eintr„ge neu_par und neu_flag setzen, in neu_par tr„gt man param ein (nur bei Ok), neu_flag setzt man auf 1 falls Ok gew„hlt wurde, -1 sonst. Dass diese Parameter von den lokalen Routinen zu setzen sind liegt daran, dass nur so die gemeinsamen Neu-Parameter der Fractal-Routinen zu realisieren waren. Rckgabewert: 0 fr Ok, 1 fr Abbruch make_neu_param void *make_neu_param(FR_OBJC *objc, void *param, X_PARAM *x_par, int *change, int *redraw, int *size); Mit dieser Routine werden aus den Daten des neu zu berechnenden Objektes und den Neu-Parametern die neuen Daten ermittlet. objc ist ein Zeiger auf das Objekt (die Objektparameter erh„lt man dann mittels objc->par->data), param ist ein Zeiger auf die Neu-Parameter, x_par einer auf die allg. Parameter des neuen Bildes (n”tig um etwa neu Farben oder Gr”sse einzutragen). 52 change, redraw und size sind Flags, um anzugeben, ob und wieweit die Parameter ge„ndert wurden. Die Flags sind beim Aufruf von make_neu_param gel”scht (0) und mssen gege- benenfalls auf 1 gesetzt werden und zwar change wenn sich irgendwas an den Parametern ge„ndert hat, redraw wenn durch eine Žnderung die Neuberechnung des Bildes n”tig ist (praktisch immer, nicht aber wenn nur die Farben ge„ndert wurden) und size wenn sich die Bildgr”sse „ndert. Zurckgegeben wird ein Zeiger auf die neuen Bildparameter (Platz fr diese reserviert man vernnftigerweise in den Neu-Parametern). make_vier void make_vier(FR_OBJC *in, void *out, int nr); Mit dieser Routine berechnet man die Parameter fr vier Bilder. in ist ein Zeiger auf das zu vergr”ssernde Objekt, out einer auf die Parameter des neuen Bildes, deren Speicher man ausnahmsweise nicht selber bereitstellen muss. nr gibt an, welches der vier Viertelbilder gemeint ist, und zwar ist 0 links oben, 1 rechts oben, 2 links unten und 3 rechts unten. do_draw int do_draw(FR_OBJC *object, void *param, void *puffer); do_draw ist die zentrale Berechnungsroutine. šbergeben wird object, ein Zeiger auf die Objekt-Struktur, param, ein Zeiger auf die Pa- rameter (eigentlich berflssig, weil identisch object->par->data) und puffer ein Zeiger auf einen 32000 Byte grossen (nicht 32kByte!) Puffer, mit dem man machen kann was man will (fast). Die Routine muss schlicht das Bild auf den Bildschirm zeichnen, alles andere erledigt CHAOSultd. Zurckgeben muss die Routine den Tastaturstatus (SHIFT, CONTROL etc.) beim Abbruch (oder Null). dont_draw void dont_draw(FR_OBJC *object,void *param); Diese Routine wird, falls existent, aufgerufen, falls ein neu erzeugtes Bild nicht gleich be- rechnet werden soll (etwa bei Berechnungsabbruch beim Erzeugen von Bildfolgen). Sie ist im allgemeinen berflssig und muss auch nicht existiern, wird aber gebraucht, wenn man etwa eingegebene Parameter als zus„tzliche Parameter verwalten will (das erm”glicht eine variable L„nge). object und param wie bei do_draw. show_par int show_par(FR_OBJC *object, long *buf); Diese Routine soll die Bildparameter des Objektes object anzeigen. buf ist ein Puffer, in den der Bildschirm bei Aufruf gerettet werden muss, der Bildschirm muss auch wieder restauriert werden. Dies geschiet am einfachsten mit den von CHAOSultd zur Verfgung gestellten Funktionen draw_objc und undraw_objc bzw. copy_screen (vgl. unten). Man 53 darf nicht den Bildschirm auf buf umstellen, da buf nicht auf eine hinreichend gerade Adresse zeigen muss. Als Rckgabewert wird eine 0 erwartet, falls sich die Parameter sicher nicht ge„ndert haben (Name oder Farben kann man unter Umst„nden hier „ndern), sonst eine 1. show_info void show_info(FR_OBJC *object, long *buf); Die Funktion show_info dient der Anzeige eines Bildinfos, abgesehen vom (nicht vorhan- denen) Rckgabewert gilt das gleiche wie bei show_par. get_info void get_info(FR_OBJC *object, PIC_INFO *info); Mit get_info holt sich CHAOSultd die Informationen die es zur Anzeige ein Bildinfos ber mehrere Bilder ben”tigt (Rechenzeit, Zahl der Iterationen und der Punkte). Existiert die Funktion show_info nicht, so wird get_info - falls es existiert - auch fr einzelne Bilder verwendet. get_objcblk void get_objcblk(FR_OBJC *object, double *x_min, double *x_max, double *y_min, double *y_max); Diese Routine gibt an CHAOSultd die Koordinaten des Bildrechteckes eines Objektes zurck, natrlich nur wenn es solche gibt. object ist ein Zeiger auf das Objekt, x_min, x_max, y_min und y_max sind Zeiger auf die Koordiaten. Falls dies Routine existiert, nimmt CHAOSultd auch an, dass der Bildschirm direkt ein Ko- ordinatensystem darstellt, d.h. dass man die Bild-Koordinaten eines Raster-Punktes durch Interpolation zwischen den Koordinaten des Bildrechteckes ermitteln kann38. Nur in diesem Fall funktioniert die Koordinatenanzeige von Bilder zeigen oder das Anzeigen eines Blockes. get_xobjcblk void get_xobjcblk(FR_OBJC *object, double *x_min, double *x_max, double *y_min, double *y_max); Die Routine entspricht exakt der Routine get_objcblk, nur dass keine Folgerungen aus ihrer Existenz gezogen werden. get_pkt void get_pkt(FR_OBJC *object, double *x, double *y); Mit der Routine get_pkt holt sich CHAOSultd die Koordinaten fr den Punkt, der bei Konstante anzeigen in Bilder zeigen angezeigt wird. Die Routine macht nur Sinn, wenn auch die Routine get_objcblk existiert. ____________________________________38 nicht der Fall ist dies z.B. bei 3d Fractalen 54 show_pktinfo void show_pktinfo(FR_OBJC *object, int x, int y, long *scr, long *buf); Diese Routine wird fr die Anzeige eine Punktinfos aufgerufen. object ist das betroffene Bildobjekt, x und y sind die (Bildschirm)-Koordinaten des Punk- tes, scr ist ein Zeiger auf den Bildschirm, in dem das Bild liegt, und buf ist ein Puffer um den Hintergrund zu retten. dr_param void dr_param(FR_OBJC *object); Die Hardcopyroutine erlaubt es Bildparameter unter die Hardcopy zu drucken. Dazu wird diese Funktion aufgerufen. object ist das ausgedruckte Objekt. Die Parameter sollten sich auf vier Zeilen beschr„nken, damit zwei grosse Bilder auf eine Druckerseite (11 Zoll) gehen. cnv_load int cnv_load(int frac_typ, L_PARAM *par, PIC_DATA *xparam, PIC_DATA *param, PIC_DATA **x_par); Diese Routine dient dazu, beim Laden die Parameter von Fraktalen anderer Aufl”sung (oder auch einer anderen Version der Berechnungsroutinen) anzupassen. šbergeben wird der Bildtyp (fr den Fall, dass mehrere Bildtypen zusammengefasst sind) in frac_typ, ein Zeiger auf zus„tzliche Parameter in par mit Gr”sse, Farben, xor-Offset etc. (vgl. Header-Datei) ein Zeiger auf die Parameter der Datei xparam, ein Zeiger auf die Parameter des Bildes param. PIC_DATA *x ist ein Zeiger auf einen Block der internen Speicherverwaltung, mit x->len erh„lt man die L„nge des Blockes + 8, x->data referenziert den Blockinhalt. Die geladenen Parameter mssen nach param kopiert werden, sie mssen ja nicht die gleiche L„nge wie die Bildparameter haben (die L„nge erh„lt man wie gesagt durch xparam->len-8). Ausserdem erh„lt man einen Zeiger auf einen Zeiger auf die (geladenen) zus„tzlichen Para- meter x_par. M”chte man letztere freigeben, so kann man dies mit pic_mfree(*x_par) tun, muss dann aber auch *x_par auf 0 setzen. Die Funktion kann 1 zurckgeben, wenn sie die Parameter nicht anpassen kann, dann wird das Laden abgebrochen. Ansonsten muss 0 zurckgegeben werden. reserved Weitere achte Eintr„ge (4 Byte) sind reserviert fr m”gliche Erweiterungen. Sie mssen auf 0 gesetzt werden; falls es Erweiterungen geben wird, werden diese natrlich optional sein. 2 Beschreibung der von CHAOSultd zur Verfgung gestellten Routinen Die von CHAOSultd zur Verfgung gestellten Routinen und Variablen sind in der COMMON- Struktur zusammengefasst. Ein Zeiger auf diese Struktur wird beim ersten Aufruf der Rou- 55 tinen unmittelbar nach dem Laden als Parameter bergeben, die Routine kann ihn dann irgendwo sichern. 2.1 Routinen CHAOSultd stellt den externen Routinen die folgenden Funktionen zur Verfgung: draw_objc void draw_objc(OBJECT *object, long *buffer); Die Funktion draw_objc zeichnet die Dialogbox, auf die der Zeiger object zeigt. buffer ist ein Zeiger auf einen 32000 Byte grossen Speicherbereich, in den vorher der Bildschirm- hintergrund kopiert wird. Ist buffer 0, so wird der Hintergrund nicht gesichert39. xdraw_objc void xdraw_objc(long *buf); xdraw_objc sichert lediglich den Bildschirm in den Puffer auf den buf zeigt (32000 Byte). Ist buf 0, so geschieht nichts (auch kein Absturz). undraw_objc void undraw_objc(long *buf); undraw_objc entfernt eine gezeichnete Dialogbox, indem es den Hintergrund aus dem Puffer buf zurckkopiert. Dies funktioniert natrlich nur, wenn man den Hintergrund auch in den Puffer gerettet hat. Anmerkung: die Funktionen draw_objc, xdraw_objc und undraw_objc schalten die Maus ab und wieder an, darum braucht man sich also nicht zu kmmern. Man sollte beim Kopieren von Bildschirmen deswegen auch diese Funktionen und nicht die unten genannte Funktion copy_screen verwenden, die solches nicht erledigt. Des weiteren sei noch angemerkt, dass die Funktionen unter Bildschirm stets den logischen Bildschirm verstehen, also den, der sich via Logbase() ermitteln l„sst. write_dbl void write_dbl(char *s, double zahl,int l,int p); Die Funktion write_dbl dient zur Ausgabe einer Fliesskommazahl zahl in einen String s. l gibt die gewnschte maximale L„nge, p die Zahl der Nachkommastellen an. Die Zahl wird zun„chst mit sprintf(str,``%*.*lf``,l,p,zahl); in einen Zwischenpuffer ausgegeben, der 128 Zeichen lang ist (sollte der String l„nger werden so ist mit Systemab- sturz zu rechnen). Anschliessend werden abschliessende Nullen entfernt (z.B. 1.2000 wird zu 1.2), lediglich eine direkt auf den Dezimalpunkt folgende Null bleibt stehen; der String wird dann mit maximal l Zeichen nach s kopiert. ____________________________________39 der Zeiger buffer darf natrlich nicht auf eine ungerade Adresse zeigen, bei den folgenden* * Routinen sei solches jeweils a priori angenommen, von CHAOSultd zur Verfgung gestellte Puffer erfllen di* *es Bedingung natrlich; genauso muss object auch wirklich ein Zeiger auf eine Dialogbox sein, andernfalls i* *st mit dem Schlimsten zu rechnen 56 Erkl„rung: bei der Ausgabe einer Fliesskommazahl mit printf kann es erstens passieren dass der String l„nger als die angegebene L„nge wird, was sich in Dialogboxen verheerend auswirken kann, zweitens werden abschliessende Nullen ausgegeben, die die Lesbarkeit der Zahlen nicht gerade erh”hen. Beides versucht zu Routine zu vermeiden, wobei im ersten Fall in Kauf genommen wird, dass die ausgegebene Zahl wom”glich verstmmelt wird. Eine Ausgabe in wissenschaftlicher Darstellung, d.h. mit Zehnerexponent, ist nicht vorgese- hen, da alle bisher von mir realisierten Routinen mit Zahlen rechnen, die nicht in Bereiche kommen, wo dies sinnvoll w„re. ipol, xipol double ipol(double anf, double end, int act_nr, int max_nr, int mode); void xipol(double anf1, double end1, double anf2, double end2, double *anf,double *end,int act_nr,int max_nr); ipol dient zur Interpolation zwischen anf und end. act_nr stellt die Nummer des gewnsch- ten Wertes, max_nr die maximale Nummer dar (da die Nummern von 0 gez„hlt werden, ist max_nr gleich der Anzahl der Nummern-1). mode bezeichnet die Art der Interpolation: _mode_|_________________________________________________________ 0 |degressive Interpolation, die Schrittweite nimmt ab 1 |lineare Interpolation, die Schrittweite ist konstant 2 ||progressive Interpolation, die Schrittweite nimmt zu 3 |Zufallszahl zwischen anf und end (keine Interpolation) xipol interpoliert ebenfalls und zwar mit Wertepaaren. Dabei „ndert sich die Differenz zwischen den beiden Werten pro Schritt um einen konstanten Faktor. anf1 und end1 sowie anf2 und end2 sind Anfangs- und Endwerte fr die beiden Werte. In anf und end werden die interpolierten Werte zurckgegeben. act_nr und max_nr sind wie oben zu verstehen. Die xipol-Routine erm”glicht das gleichm„ssige Vergr”ssern von Bl”cken. Interpoliert man dabei die Koordinaten linear, so ergibt sich am Ende ein gr”sserer Vergr”sserungsfaktor, da die absolute Žnderung konstant ist. Durch die degressive Interpolation wird dies zwar abgeschw„cht, aber nicht wirklich behoben. Die xipol-Routine berechnet die Zwischenwerte dagegen so, dass sich ein konstanter Vergr”sserungsfaktor ergibt. plot_pixel void plot_pixel(int x, int y,void *addr); void plot_pixel(int x, int y,int col,void *addr); Die Routine plot_pixel zeichnet einen Punkt. Die erste Deklaration gilt fr die sw-Version, die zweite fr die Farbversion. x und y beschreiben die Koordinaten des Punktes (in der blichen Weise, die linke obere Bildschirmecke ist (0,0)). addr ist ein Zeiger auf den Bildschirmspeicher, in dem der Punkt gesetzt werden soll. col bezeichnet die Farbe, die der Punkt erhalten soll. In der sw-Version werden lediglich Punkte gesetzt, L”schen ist nicht m”glich, deshalb wird auch keine Farbe ben”tigt40. ____________________________________40 in der Farbversion kann man durch col=0 Punkte auch l”schen 57 Die unterschiedliche Deklaration der Funktion in den beiden Modi ist ein bisschen l„stig, man kann sie aber durch Definition eines Makros unterdrcken: #define pl_pixel(x,y,col,addr) plot_pixel(x,y,addr) in der sw-Version bzw. in der Farb-Version: #define pl_pixel(x,y,col,addr) plot_pixel(x,y,col,addr) So kann man in beiden F„llen eine Farbe angeben, sollte natrlich immer bedenken, dass diese in der sw-Version ignoriert wird. Alternativ k”nnte man die Deklaration fr die Farb-Version auch fr die sw-Version ver- wenden, dann wird eben ein zus„tzlicher Parameter (in D2) bergeben, den die aufgerufene Funktion schlicht ignoriert. set_point void set_point(int x,int y,int col,int flag); set_point zeichnet ebenfalls Punkte. Diese Funktion darf nur beim Zeichnen von Bildern (also in der Routine do_draw) aufgerufen werden. Sonstiger Gebrauch wird mit Absturz nicht unter zwei Bomben geahndet! x und y sind wieder die Bildschirmkoordinaten des Punktes, col seine Farbe. flag ist in der Farb-Version redundant, in der sw-Version wird mittels flag zwischen Einzelpixeln und 4er- Gruppen unterschieden. Ist flag 0 so wird ein einzelnes Pixel gesetzt (nicht gel”scht, col hat dann wieder keine Bedeutung). Ist flag 1 so wird ein aus vier Pixeln ((x,y), (x+1,y), (x,y+1) und (x+1,y+1)) bestehender Bildpunkt in der Graustufe col gesetzt. col kann die Werte 0 (weiss), 1 (ein Punkt), 2 (zwei diagonal liegende Punkte), 3 (ein Punkt nicht) und 4 (schwarz) annehmen. Auch hier werden grunds„tzlich Punkte nur gesetzt! get_pixel int get_pixel(int x,int y,void *addr); get_pixel liefert die Farbe des Bildpunktes (x, y) im Bildschirm addr copy_screen void copy_screen(long *s,long *d); copy_screen kopiert (ziemlich schnell) 32000 Byte von s (wie Source) nach d (wie Destina- tion). Da dies genau die L„nge eines Bildschirmes ist (Overscan geht ja nicht) erkl„rt sich wohl auch der Name. clr_screen void clr_screen(long *s); clr_screen l”scht 32000 Byte ab s. pic_malloc, pic_mfree und check_mem PIC_DATA *pic_malloc(long len,PIC_DATA **mother); void pic_mfree(PIC_DATA *addr); int check_mem(long len); 58 Diese Funktionen erlauben der Zugriff auf die interne Speicherverwaltung, der aber nicht ganz unproblematisch ist. Das Problem besteht vor allem in der Belegung von Speicher durch die do_draw-Routine (etwa als zus„tzliche Parameter), da sichergestellt sein muss, dass fr das Ablegen des be- rechneten Bildes garantiert genug Speicher brigbleibt. Ich m”chte an dieser Stelle nicht weiter auf diese Funktionen eingehen, da man meist auch ohne sie auskommen drfte. Falls die Berechnungsroutinen generell zus„tzlichen Speicher brauchen, so sollten sie ihn in der do_init-Routine vom TOS (also mit Malloc) anfordern. gettime long gettime(void); Die Funktion gettime liefert den akutellen Wert des 200 Hz Z„hlers (also den Wert der Systemvariablen an der Adresse $4BA). get_objc, get_obblk, get_konst und get_block FR_OBJC *get_objc(int typflag); int xget_obblk(FR_OBJC *objc, double *x_min, double *x_max, double *y_min, double *y_max); FR_OBJC *get_konst(int typflag, double *x, double *y); FR_OBJC *get_block(int typflag, double *x_min, double *x_max, double *y_min, double *y_max); Diese Funktionen erm”glichen die šbernahme von Parametern bestehender Bilder bei der Eingabe von Parametern. Die Funktion get_objc liefert einen Zeiger auf ein Objekt, das der Anwender auf dem Desktop ausw„hlen kann, zurck (oder 0, falls kein Objekt gew„hlt wurde). typflag gibt an, welche Objekte gew„hlt werden k”nnen: ist typflag -1, so k”nnen beliebige Fractale, -2 beliebige Bilder (nicht Filme) gew„hlt werden. Ansonsten kann noch ein positiver Wert (gr”sser 1) angegeben werden, dann k”nnen nur Fractale dieses Types ausgew„hlt werden (normalerweise ist das dann natrlich die Typnummer der eigenen Routinen, wie man sie beim Initialiseren bergeben bekommt). Der Bildschirmaufbau der Eingabefunktion wird von dieser Routine nicht ver„ndert. Die Funktion get_obblk liefert - falls m”glich - in den Rckgabeparametern x_min, x_max, y_min und y_max das Koordinatenrechteck des Objektes objc zurck. Als Rckgabewert wird 0 geliefert, wenn kein Rechteck ermittelt werden konnte, 1 bedeutet, dass die Werte in x_min, x_max, y_min und y_max gltig sind. Mit der Funktion get_konst kann man den Benutzer eine Koordinate in einem Bild, mit get_block einen Ausschnitt w„hlen lassen. Rckgabewerte sind x und y bzw. x_min, x_max, y_min und y_max sowie (als dierektes Funktionsergebnis) ein Zeiger auf des Objekt in dem die Koordinate bzw. der Ausschnitt liegt. Ein Rckgabewert von 0 bedeutet, dass kein Objekt ausgew„hlt wurde (oder im ausgew„hl- ten Objekt kein Block/keine Konstante bestimmt werden kann); in diesem Fall ist der Bildschirmaufbau der Eingabefunktion nicht ver„ndert. Ein Rckgabewert von -1 bedeutet einen Abbruch der Auswahl beim Markieren der Konstante/des Blockes. In diesem Fall wurde das Bild schon angezeigt, so dass der Bildschirm der Eingabefunktion berschrieben 59 wurde; dargestellt wird dann wieder der CHAOSultd-Desktop und man muss die Dialogbox neu zeichnen lassen. typflag wird wie bei get_objc ausgewertet (-2 ist natrlich nicht sehr sinnig, da in Bildern ohne Parameter natrlich keine Koordinaten zur Verfgung stehen). fsel int fsel(char *path,char *sel,int *button,char *label); Aufruf der Dateiselectorbox entsprechend fsel_exinput, allerdings wird bei „lteren AES- Versionen automatisch (unter Unterdrckung von label) fsel_input verwendet. dr_string void dr_string(char *str); Ausgabe eines Strings str auf den Drucker entsprechend der gew„hlten Ausgabefunktion. Zum Drucken der Parameter unter eine Hardcopy ist diese Funktion vernnftigerweise zu verwenden, da man sich dann nicht selber um den eingestellen Ausgabemodus kmmern muss. set_unoutlined void set_unoutlined(FR_OBJC *object); Die Funktion set_unoutlined setzt fr das Objekt object den Status nicht fertig, etwa wenn man (wie bei Hpfer m”glich) nachtr„glich die Zahl der gewnschten Iterationen erh”ht. irand und xrand long irand(long dummy); double xrand(long dummy); Zufallszahlengenerator nach D. Knuth. irand liefert eine (Long-)Integer Zufallszahl zwi- schen 0 und 1000 000 000, xrand eine Fliesskomma-Zufallszahl zwischen 0 und 1. dummy dient der Initialisierung: ist dummy ungleich Null, so wird der Zufallszahlengenerator (fr beide Routinen gemeinsam!) initialisiert und zwar mit einem zuf„lligen Wert (aus dem xbios-Zufallszahlengenerator) falls dummy -1 ist, mit dummy selbst sonst. Man beachte, dass die Zufallszahlen nach der Initialisierung mit einem bestimmten Wert natrlich deterministisch und wiederholbar sind, initialisieren sollte man den Zufallszahlen- generator auch nur einmal am Anfang einer Routine (wenn man ihn bei jedem Aufruf auf einen festen Wert initialisiert, dann wird er auch immer den gleichen Wert liefern!). conv_time void conv_time(unsigned long ms, int *h, int *m, double *s); Konvertiert die in Millisekunden angegebene Zeit ms in Stunden h, Minuten m und Sekunden s. Man beachte, dass der letzte Wert als Fliekommazahl zurckgegeben wird. 60 conv_sc_mm und conv_mm_sc void conv_sc_mm(double scale, double offset, int delta, double *min, double *max); void conv_mm_sc(double min, double max, int delta, double *scale, double *offset); Mit diesen Routinen kann man zwischen der Definition von Bildschirmkoordinaten durch Nullpunkt und Vergr”sserung (offset/scale) und durch minimalen und maximalen Achsen- abschnitt umrechnen. delta gibt die halbe H”he bzw. Breite des gesamten Bildschirms an ( delta ist also die maximale und minimale Koordinate bei scale 1 und offset 0. Spezielle Funktionen fr die Farb-Version Die folgenden Funktionen existieren nur in der Farb-Version: make_alert, make_drawobjc und make_undraw int make_alert(int button,int *coltab,char *alert); void make_drawobjc(OBJECT *objc); void make_undraw(int *coltab); Mit diesen Funktionen kann w„hrend des Berechnens eines Bildes eine Alert- bzw. Dialogbox ausgegeben werden. Das Problem besteht dabei im Aufl”sungswechsel, da fr die Berech- nung in niedrige Aufl”sung geschaltet wurde, fr die AES-Ausgabe aber mittlere Aufl”sung gebraucht wird. make_alert gibt eine Alertbox aus. button und alert entsprechen den Parametern von form_alert, coltab ist ein Zeiger auf die Farbtabelle des Bildes (blicherweise die, die auch in der FR_OBJC-Struktur steht). Zurckgegeben wird der Rckgabewert von form_alert also der ausgew„hlte Button. make_drawobjc und make_undraw sind die Analoga zu draw_objc und undraw_objc, wobei ein Puffer nicht angegeben werden muss. Fr make_undraw muss man wie bei make_alert die Farbtabelle angeben. Die Dialogbox wird bei make_drawobjc nur gezeichnet, nicht auf- gerufen (mit form_do, dies bleibt der externen Routine vorbehalten. Achtung! Die Routinen ben”tigen als Zwischenspeicher den Puffer, der auch der Zeichen- routinen do_draw zur Verfgung steht. Der Inhalt dieses Puffers geht deshalb beim Aufruf einer dieser Routine verloren! Zur Ausgabe von Dialogboxen beim Anzeigen von Parametern etc. darf man diese Funktio- nen nicht verwenden, dort man gibt einfach die Dialogbox (z.B. mit draw_objc) aus. set_colors void set_colors(int *col_tab,long *scrn,FR_OBJC *object,int flag); Die Funktion set_colors dient zur Einstellung der Farbtabelle. Wird sie von externen Routinen aufgerufen, so muss der Parameter scrn 0 sein, flag dagegen 1. col_tab zeigt natrlich auf die einzustellende Farbtabelle, bleibt noch object. object ist 0 oder ein Zeiger auf ein Bild-Objekt; im letzteren Fall wird im oberen Bildteil bei der Farbeinstellung das Bild, sonst einfach Farbbalken dargestellt. L„sst man die Farben eines bestehenden Bildes „ndern, so sollte man natrlich einen Zeiger auf dieses Bild bergeben. 61 2.2 Variable CHAOSultd stellt noch eine Reihe von Variablen mit verschiedenen Daten zur Verfgung. Alle diese Werte sind ausschliesslich read-only - Žnderungen darf man nicht vornehmen. fr_x0, fr_y0, fr_dx, fr_dy und pic_size int *fr_x0; int *fr_y0; int *fr_dx; int *fr_dy; int *pic_size; int *line_len; Integer-Arrays mit jeweils drei Eintr„gen fr die drei Bildgr”ssen 0 (klein), 1 (mittel) und* * 2 (gross). fr_x0 und fr_y0 enthalten die Koordinaten der linken oberen Ecke, fr_dx und fr_dy die Breite bzw. H”he der Bilder in Pixeln minus 1! pic_size enth„lt die L„nge (ungepackter) Bilddaten in Byte, line_len ist die L„nge einer Zeile, ebenfalls in Byte und zwar pro Bildebene. Die Arrays enthalten die folgenden Werte: #ifdef COLOR int fr_x0[3]=-80,48,0"; int fr_y0[3]=-50,30,0"; int fr_dx[3]=-159,223,319"; int fr_dy[3]=-99,139,199"; int line_len[3]=-20,28,40"; #else int fr_x0[3]=-160,96,0"; int fr_y0[3]=-100,60,0"; int fr_dx[3]=-319,447,639"; int fr_dy[3]=-199,279,399"; int line_len[3]=-40,56,80"; #endif int pic_size[]=-8000,15680,32000"; scr long *scr; scr ist nur gltig w„hrend des Zeichnens von Bildern. Dann zeigt scr auf den Bildschirm, und kann (und sollte) fr plot_pixel-Aufrufe verwendet werden. settings CHS_SET *settings; settings ist ein Zeiger auf die Einstellungen von CHAOSultd. Die CHS_SET-Struktur ist in der Headerdatei definiert. 62 reserved Auch in dieser Struktur ist Platz fr Erweiterungen gelassen, hier sogar 16 Lang-Worte, die alle auf Null gesetzt sind. 3 Vorgehensweise Zun„chst einmal kann man sich, nachdem man diese Beschreibung gelesen hat, die Beispiel- routinen fr Feigenbaumdiagramme anschauen. M”chte man eigene Routinen verwirklichen, so sollte man sich als erstes die n”tigen Para- meter berlegen, und eine entsprechende Struktur fr die Bildparameter definieren, ebenso eine fr die Eingabeparameter. Dann muss man die Eingaberoutinen schreiben (natrlich nicht unbedingt gleich mit allen Details) und die Routine zur Erzeugung des Bildparameter aus den Eingabeparametern; das Laden der n”tigen Resourcedatei erledigt man in der do_init-Routine. Hat man dies geschafft, so fehlt nur noch das Herz aller Berechnungsroutinen, n„mlich die eigentliche Zeichen-Routine. Hat man alle diese Routinen mehr oder weniger fertig, so erstellt man eine CHAOS-Struktur, in die man alle Routinen und anderen Daten eintr„gt; fr noch nicht existierende Routinen tr„gt man 0 ein. Anmerkung: in der CHAOS-Struktur tauchen jede Menge Zeiger auf void auf, die man in Deklarationen konkreter Berechnungsroutinen natrlich besser durch Zeiger auf die jewei- ligen Strukturen ersetzt. Die Warnungen vor verd„chtigen Zeigerumwandlungen, die dann bei Eintrag der Routinen in eine CHAOS-Struktur auftreten, kann man beispielsweise durch das Pr„prozessorkommando #pragma warn -sus unterdrcken (falls man die Warnungen nicht in den Compiler-Optionen eh abgeschaltet hat). Um die CHAOS-Struktur nun bei der Initialisierung an CHAOSultd zurckzugeben braucht man noch eine XCHAOS-Struktur, die aus Sicherheitsgrnden und fr die šbergabe mehrerer CHAOS-Strukturen n”tig ist. Die XCHAOS-Struktur besteht aus einer 8 Byte langen Id in die man "CHSultd5" eintr„gt, der Anzahl der Routinen (anz) sowie einem Zeiger auf ein Array mit Integer-Flags (flag) und einem Zeiger auf ein Array mit CHAOS-Strukturen (chs)41. In den Flags muss das unterste Bit gesetzt sein, falls die Routine sw-tauglich ist, das 2. Bit steht fr Farbtauglichkeit (l"* *auft die Routine in beiden Aufl”sungen, so setzt man eben beide Bits); die anderen Bits sind reserviert und auf Null zu setzen). Hat man dies geschafft, so schreibt man noch die šbergaberoutine fr die Parameter (ana- log der der Feigenbaum-Diagramme); dann kann man sein Programm bersetzen und via CHAOSultd aufrufen. Beim Linken kann und sollte man brigens die Stack-Gr”sse auf Null setzen, da ohnedies der Stack von CHAOSultd verwendet wird; ein eigener Stack w„re nur Speicherplatzverschwen- dung. Der Stack von CHAOSultd ist brigens 8 kByte gross und drfte bei allen externen Funktionen problemlos mit bis zu 6 kByte belastbar sein. Ein echtes Problem ist das Debuggen, der Source-Level-Debugger hilft einem so gut wie garnicht und auch Low-Level-Debugging geht nur ohne Label, also praktisch auch nicht. ____________________________________41 es kann natrlich auch jeweils nur ein Wert vorhanden sein, dann ist anz halt 1 und flag z* *eigt auf einen Integer-Wert, chs auf eine CHAOS-Struktur 63 Wer hier Probleme hat, kann sich ja mal mit mir in Verbindung setzen, eventuell stelle ich auch die Sourcen von CHAOSultd zur Verfgung, so dass die Routinen als Bestandteil des Programmes entwickelt und so auch anst„ndig debuggt werden k”nnen. Eine generelle Frei- gabe des Sourcecodes kommt aber nicht in Frage, dieser Hinweis steht nicht unbeabsichtigt an wenig herausragender Stelle. Weitere Hinweise An Algorithmen kommen im Prinzip alle Algorithmen in Frage, die Bilder um ihrer selbst willen erzeugen - natrlich auch wenn sie nicht chaotisch sind42. Dabei sollte der Algorithmus aber auch eine gewisse Bandbreite an verschiedenen Bildern bieten, Algorithmen, die die Erzeugung genau eines Bildes erm”glichen, sind ja vielleicht ganz nett, in CHAOSultd aber fehl am Platze, es ist in solchen F„llen allemal einfacher, ein Programm zu schreiben, dass ein solches Bild berechnet und auf den Bildschirm ausgibt, so dass man es mit einem Screen-Dump-Programm abspeichern kann. CHAOSultd ist dazu gedacht, viele Bilder zu berechnen; das Programm untersttzt durch Berechnungsabbruch und -fortsetzen insbesondere das Berechnen von Bildern ber Nacht oder wenn man sonst nicht da ist43. Deswegen sollte man dem Benutzer bei der Wahl der Parameter freie Hand lassen und so m”glichst viel Variationen zulassen. Die Routinen sollten auch, so wie die vorhandenen, die Berechnung von Bildfolgen erm”gli- chen. In jedem Fall sind fr die Parametereingabe GEM-Dialoge zu verwenden. Man sollte dabei darauf achten, dass alle Parameter in beliebiger Reihenfolge angegeben werden k”nnen, braucht man mehr als eine Dialogbox, so sollte man zwischen diesen hin- und herschalten k”nnen, bzw. die zweite Dialogbox w„re als Unterdialog (wie beim Farben einstellen fr Fractale) zu realisieren44. Soweit irgendm”glich sollten die Routinen den Benutzer bei der Eingabe der Parameter untersttzen, insbesondere die šbernahme von Parametern aus bestehenden Objekten sollte m”glich sein. Sehr viele der Routinen sind optional, das heisst aber nicht, dass externe Routinen auf sie alle verzichten k”nnen. Eine Option sollte nur dann weggelassen werden, wenn sie sich fr den implementierten Bildtyp nicht, praktisch nicht oder nur mit unverh„ltnism„ssig grossem Aufwand realisieren l„sst. Ich denke die von mir bisher geschriebenen Routinen erfllen diese Forderungen recht gut - am wenigsten die Feigenbaum-Routinen, die sind aber auch vor allem als Beispiel zur Einbindung externer Berechnungsroutinen entstanden. Generell sollte man sich diese Routinen zum Vorbild nehmen, nicht nur weil ich sie fr ganz brauchbar halte, sondern auch, weil Einheitlichkeit fr ein Programm wie CHAOSultd umso wichtiger ist, je mehr Routinen es gibt (vermutlich schreibt ja eh keiner welche und ich k”nnte mir das ganze gelabere sparen). Zur Schnittstelle gibt es noch zu sagen, dass sie h”chstens erweitert wird, nicht * * aber ver„ndert, es sei denn, irgendeine unvorhergesehene Katastrophe tritt auf. Fr CHAOS- ____________________________________42 nicht geeignet ist CHAOSultd allerdings fr bewegte Bilder (etwa zellul„re Automaten) 43ein Punkt den externe Routinen auf jeden Fall untersttzen sollten, wenngleich dies fr m* *anche Berech- nungsmethoden m”glicherweise nicht realisieren l„sst 44die Eingabe der Berechnungsformel fr freidef. Fract. natrlich ein Verstoss gegen diese * *Regel 64 ultd V5.0 entwickelte exteren Routinen werden somit auch (ohne Žnderungen) mit allen weiteren Version von CHAOSultd V5.x zusammenarbeiten. Dies gilt allerdings nicht fr eine etwaige GEM-Version. Da ich dafr das Programm mehr oder weniger neu entwickeln msste (weshalb es eine GEM-Version auch nicht so bald geben wird) wird auch die Schnittstelle neu definiert werden. 65